package com.delivery.interceptor;

import com.delivery.constant.JwtClaimsConstant;
import com.delivery.context.BaseContext;
import com.delivery.properties.JwtProperties;
import com.delivery.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Slf4j
@Component
public class JwtTokenUserInterceptor implements HandlerInterceptor {

    @Autowired
    private JwtProperties jwtProperties;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        // 放行 OPTIONS 请求（CORS 预检）
        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
            return true;
        }

        // 检查当前请求是否映射到Controller中的方法（即HandlerMethod）
        if (!(handler instanceof HandlerMethod)) {
            // 如果不是Controller方法（例如静态资源、过滤OPTIONS等），直接放行拦截器
            return true;
        }

        // 获取请求url。
        String uri = request.getRequestURI();
        log.info("uri = {}", uri);

        // 判断请求url中是否包含login，如果包含，说明是登录操作，放行。
        if (uri.contains("login")){
            return true;
        }

        // 获取请求头中的令牌（token）。
        String token = request.getHeader(jwtProperties.getUserTokenName());

        // 解析token，如果解析失败，响应401 。
        try {
            Claims claims = JwtUtil.parseJWT(jwtProperties.getUserSecretKey(),token);
            log.info("claims = {}", claims);
            // 获取当前登录用户的ID，将当前登录用户的ID保存到ThreadLocal中。
            BaseContext.setCurrentId(Long.valueOf(claims.get(JwtClaimsConstant.USER_ID).toString()));
        } catch (Exception e) {
            log.error("令牌解析失败：{}", e.getMessage());
            response.setStatus(HttpStatus.UNAUTHORIZED.value());
            // 不放行
            return false;
        }

        // 放行
        return true;
    }
}
